package net.mohas.docsearch.util;

import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

/**
 * 
 * @author Muhammad
 *
 */
public class FileUtil {

	/**
	 * Return a list of file paths in a directory if the given path is a path to a directory. 
	 * If the given path is a path to a file, it will return the file path in a list. 
	 * The list has been filtered with file filter specified. All files will be accepted if the filter is <code>null</code>.
	 * 
	 * @param path Path to a file or a directory
	 * @param filter  A file filter
	 * @return List of file paths
	 * 
	 */
	public static List<File> listAllFiles(String path, FileFilter filter) {
		List<File> list = new ArrayList<File>();
		File file = new File(path);
	
		if (file.isFile()) {
			list.add(file);
			
		} else if (file.isDirectory()) {
			Queue<File> fileQueue = new LinkedList<File>();
			
			File[] files = file.listFiles(filter);
			
			if (files.length > 0) {
				
				for (int i = 0; i < files.length; i++) {
					fileQueue.add(files[i]);
				}
			}
			
			while (!fileQueue.isEmpty()) {
				File f = fileQueue.poll();
				
				if (f.isFile()) {
					list.add(f);
					
				} else if (f.isDirectory()) {
					File[] fs = f.listFiles(filter);
					if (fs.length > 0) {						
						for (int i = 0; i < fs.length; i++) {
							fileQueue.add(fs[i]);
						}					
					}
				}
			}
		}

		return list;
	}

	public static void main(String[] args) {
		String path = "D:\\Book";
		
		FileFilter filter = new FileFilter() {
			public boolean accept(File pathname) {
				if (pathname.isFile()) {
					return pathname.getName().endsWith("pdf");
				} else if (pathname.isDirectory()) {
					return true;
				}
				return false;
			}
		};
		
		List<File> list = FileUtil.listAllFiles(path, filter);
		System.out.println("Total: " + list.size());
		for (File file : list) {
			System.out.println(file.getAbsolutePath());
		}
	}

}
